package com.zmn.oms.dubbo.impl.zmn.master.part;

import com.zmn.common.constant.StatusConsts;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.common.constant.OrderFailConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.model.entity.work.OrderWork;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.business.interfaces.work.masterwork.MasterWorkBService;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.dubbo.dto.common.express.ExpressCompanyDRO;
import com.zmn.oms.dubbo.dto.common.part.ApplyFactoryPartCheckDRO;
import com.zmn.oms.dubbo.dto.common.part.FactoryPartDRO;
import com.zmn.oms.dubbo.dto.common.part.FactoryPartPostCheckDRO;
import com.zmn.oms.dubbo.dto.common.part.FactoryPartPostDIO;
import com.zmn.oms.dubbo.dto.common.work.*;
import com.zmn.oms.dubbo.dto.zmn.part.fcpart.FcOrderPartRespDRO;
import com.zmn.oms.dubbo.impl.OmsBaseRemoteService;
import com.zmn.oms.dubbo.interfaces.zmn.master.part.MasterPartRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.dto.fcorderpart.ApplyFactoryPartCheckDTO;
import com.zmn.oms.model.dto.fcorderpart.FcOrderPartRespDTO;
import com.zmn.oms.model.dto.fcorderpart.OrderFactoryPartDTO;
import com.zmn.oms.model.dto.part.FactoryPartDTO;
import com.zmn.oms.model.dto.part.FactoryPartPostDTO;
import com.zmn.oms.model.dto.work.masterwork.MasterPartRetainDTO;
import com.zmn.oms.model.dto.work.masterwork.UsePartDTO;
import com.zmn.oms.model.dto.work.masterwork.WorkDetailDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsPartDTO;
import com.zmn.oms.model.entity.factory.OrderFactory;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.part.ZsOrderFactoryPartBService;
import com.zmn.oms.zmn.business.interfaces.work.masterwork.ZsMasterWorkBService;
import com.zmn.tapi.common.expressage.ExpressageCompany;
import com.zmn.tapi.dubbo.interfaces.expressage.ExpressageRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 类描述：工程师配件
 *
 * @author heciqi
 * @date 2020/03/27 13:48
 */
@Slf4j
@Service(loadbalance = "roundrobin", timeout = 20000, retries = 2, version = DubboConsts.INTERFACE_VERSION)
public class MasterPartRemoteServiceImpl extends OmsBaseRemoteService implements MasterPartRemoteService {
	@Autowired
	private ZsMasterWorkBService zsMasterWorkBService;
	@Autowired
	private ZsOrderFactoryPartBService zsOrderFactoryPartBService;
	@Autowired
	private OrderFactoryService orderFactoryService;
	@Autowired
	private OrderWorkService orderWorkService;
	@Autowired
	private MasterWorkBService masterWorkBService;
//	@Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
//	private FactoryListRemoteService factoryListRemoteService;
	@Reference(version = com.zmn.tapi.dubbo.DubboConsts.INTERFACE_VERSION, check = false)
	private ExpressageRemoteService expressageRemoteService;
	/**
	 * 标记为使用配件
	 *
	 * @param usePartDIO
	 */
	@Override
	public ResponseDTO modifyUsePart(BaseRequestDIO usePartDIO) {
		try {
			UsePartDTO usePartDTO = BeanMapper.map(usePartDIO, UsePartDTO.class);
			super.setLogParam(usePartDIO, usePartDTO);

			zsMasterWorkBService.updateUsePart(usePartDTO);
			return ResponseDTO.success();
		} catch (OmsBaseException e) {
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 工程师用配件
	 *
	 * @param usePartDIO
	 */
	@Override
	public ResponseDTO<WorkDetailDRO> modifyPart(UsePartDIO usePartDIO) {
		try {
			ZsPartDTO zsPartDTO = BeanMapper.map(usePartDIO, ZsPartDTO.class);
			this.setLogParam(usePartDIO, zsPartDTO);
			logger.info("保存工程师配件zsPartDTO[{}]", zsPartDTO);
			ResponseDTO responseDTO = zsMasterWorkBService.updatePart(zsPartDTO);

			// 返回更新后的工单详情
			WorkDetailDTO workDetail = zsMasterWorkBService.getWorkDetailSrcMaster(usePartDIO.getPlat(),
					usePartDIO.getOrderId(), usePartDIO.getWorkId(), usePartDIO.getMasterId(), usePartDIO.getAgent());

			// 提示优惠变更消息
			if (Objects.equals(responseDTO.getStatus(), OrderFailConsts.FAIL_DATA_CHANGE_CLEAR_ENGINEER_DISCOUNT)) {
				workDetail.setPartMsg(responseDTO.getMessage());
			}

			WorkDetailDRO workDetailDRO = BeanMapper.map(workDetail, WorkDetailDRO.class);
			return ResponseDTO.success(workDetailDRO);
		} catch (OmsBaseException e) {
			log.error("保存工程师配件失败", e);
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 工程师取消配件
	 *
	 * @param cancelPartDIO
	 */
	@Override
	public ResponseDTO<WorkDetailDRO> cancelPart(CancelPartDIO cancelPartDIO) {
		try {
			ZsPartDTO zsPartDTO = new ZsPartDTO();
			this.setLogParam(cancelPartDIO, zsPartDTO);
			zsPartDTO.setUsed(GlobalConsts.NO);

			ResponseDTO responseDTO = zsMasterWorkBService.cancelPart(zsPartDTO);

			// 返回更新后的工单详情
			WorkDetailDTO workDetail = zsMasterWorkBService.getWorkDetailSrcMaster(cancelPartDIO.getPlat(),
					cancelPartDIO.getOrderId(), cancelPartDIO.getWorkId(), cancelPartDIO.getMasterId(),
					cancelPartDIO.getAgent());

			// 提示优惠变更消息
			if (Objects.equals(responseDTO.getStatus(), OrderFailConsts.FAIL_DATA_CHANGE_CLEAR_ENGINEER_DISCOUNT)) {
				workDetail.setPartMsg(responseDTO.getMessage());
			}

			WorkDetailDRO workDetailDRO = BeanMapper.map(workDetail, WorkDetailDRO.class);
			return ResponseDTO.success(workDetailDRO);
		} catch (OmsBaseException e) {
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 工程师申请厂家配件
	 *
	 * @param orderFactoryPartDIO
	 */
	@Override
	public ResponseDTO applyFactoryPart(OrderFactoryPartDIO orderFactoryPartDIO) {
		try {
			OrderFactoryPartDTO orderFactoryPartDTO = BeanMapper.map(orderFactoryPartDIO, OrderFactoryPartDTO.class);
			this.setLogParam(orderFactoryPartDIO, orderFactoryPartDTO);

			zsOrderFactoryPartBService.applyFcPart(orderFactoryPartDTO);

			/*OrderFactory orderFactory = orderFactoryService.findOrderFactoryByKey(orderFactoryPartDTO.getOrderId());
			ResponseDTO<FactoryDRO> resultDTO = factoryListRemoteService.getFactoryById(orderFactory.getFactoryId());
			if (resultDTO.isSuccess()) {
				FactoryDRO factoryDRO = resultDTO.getData();
				String phone = factoryDRO.getMobile();
				String msg = String.format("工单%s申请了厂商配件，请您及时审核", orderFactoryPartDIO.getOrderId());
				//MQPushUtil.sendBizSmsInfo(phone, String.format(SMS_TEMPLATE_TO_FACTORY, msg)); 2019-12-26 需求暂时删除
			} else {
				logger.info(String.format("【申请厂家配件】短信通知发送失败，%s", resultDTO.getMessage()));
			}*/

			return ResponseDTO.success();
		} catch (OmsBaseException e) {
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 工程师获取需要返厂的配件
	 *
	 * @param baseRequestDIO
	 * @return
	 */
	@Override
	public ResponseDTO<List<FactoryPartDRO>> listToPostReturnFcPart(BaseRequestDIO baseRequestDIO) {
		OmsOperator omsOperator = BeanMapper.map(baseRequestDIO, OmsOperator.class);
		this.setLogParam(baseRequestDIO, omsOperator);

		List<FactoryPartDTO> fcPartDTOList = zsOrderFactoryPartBService.getToPostReturnFcPart(omsOperator);
		List<FactoryPartDRO> fcPartDROList = BeanMapper.mapList(fcPartDTOList, FactoryPartDRO.class);

		return ResponseDTO.success(fcPartDROList);
	}

	/**
	 * 邮寄配件（旧件返厂）
	 *
	 * @param factoryPartPostDIO
	 * @return
	 * @see
	 */
	@Override
	public ResponseDTO<FactoryPartPostCheckDRO> postReturnFcPart(FactoryPartPostDIO factoryPartPostDIO) {
		try {
			FactoryPartPostDTO factoryPartPostDTO = BeanMapper.map(factoryPartPostDIO, FactoryPartPostDTO.class);
			this.setLogParam(factoryPartPostDIO, factoryPartPostDTO);

			zsOrderFactoryPartBService.updatePostReturnFcPart(factoryPartPostDTO);
			// 需要返回是否还存在未邮寄的返厂配件
			boolean contains = zsOrderFactoryPartBService.containsToPostReturnFcPart(factoryPartPostDTO.getOrderId());
			FactoryPartPostCheckDRO checkDRO = new FactoryPartPostCheckDRO();
			checkDRO.setContainsReturnFcPartWaiting4Post(contains ? GlobalConsts.YES : GlobalConsts.NO);

			/*OrderFactory orderFactory = orderFactoryService.findOrderFactoryByKey(factoryPartPostDIO.getOrderId());
			ResponseDTO<FactoryDRO> resultDTO = factoryListRemoteService.getFactoryById(orderFactory.getFactoryId());

			if (resultDTO.isSuccess()) {
				FactoryDRO factoryDRO = resultDTO.getData();
				String phone = factoryDRO.getMobile();
				String msg = String.format("工单%s的旧件已经邮寄，快递单号：%s，您可登录系统查看物流信息",
						factoryPartPostDIO.getOrderId(), factoryPartPostDTO.getExpressCode());
				//MQPushUtil.sendBizSmsInfo(phone, String.format(SMS_TEMPLATE_TO_FACTORY, msg)); 2019-12-26 需求暂时删除
			} else {
				logger.info(String.format("【旧件返厂】短信通知发送失败，%s", resultDTO.getMessage()));
			}*/

			return ResponseDTO.success(checkDRO);
		} catch (OmsBaseException e) {
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 获取配件物流信息
	 *
	 * @param baseRequestDIO
	 * @return
	 */
	@Override
	public ResponseDTO<FcOrderPartRespDRO> getExpressParts(BaseRequestDIO baseRequestDIO) {
		try {
			FcOrderPartRespDTO fcOrderPartRespDTO = zsOrderFactoryPartBService.getExpressParts(baseRequestDIO.getOrderId());
			FcOrderPartRespDRO fcOrderPartRespDRO = BeanMapper.map(fcOrderPartRespDTO, FcOrderPartRespDRO.class);
			return ResponseDTO.success(fcOrderPartRespDRO);
		} catch (OmsBaseException e) {
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 通过ID查询配件物流信息，用于修改快递记录
	 *
	 * @param fcOrderPartId
	 * @return
	 */
	@Override
	public ResponseDTO<FactoryPartDRO> getExpressPartById(Integer fcOrderPartId) {
		try {
			FactoryPartDTO factoryPartDTO = zsOrderFactoryPartBService.getExpressPartById(fcOrderPartId);
			FactoryPartDRO factoryPartDRO = BeanMapper.map(factoryPartDTO, FactoryPartDRO.class);
			return ResponseDTO.success(factoryPartDRO);
		} catch (OmsBaseException e) {
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 获取快递公司
	 *
	 * @return
	 */
	@Override
	public ResponseDTO<List<ExpressCompanyDRO>> listExpressesCompany() {
		Map<String, String> map = expressageRemoteService.listCompany().getData().stream().collect(Collectors.toMap(ExpressageCompany::getCode, ExpressageCompany::getName));;
		List<ExpressCompanyDRO> list = new LinkedList();
		for (String key : map.keySet()) {
			ExpressCompanyDRO obj = new ExpressCompanyDRO();
			obj.setCode(key);
			obj.setName(map.get(key));
			if (!obj.getName().contains("订单")) {
				list.add(obj);
			}
		}
		return ResponseDTO.success(list);
	}

	/**
	 * 申请厂商配件操作检查
	 *
	 * @param baseRequestDIO
	 * @return
	 */
	@Override
	public ResponseDTO<ApplyFactoryPartCheckDRO> applyFactoryPartCheck(BaseRequestDIO baseRequestDIO) {
		try {
			ApplyFactoryPartCheckDTO checkDTO = zsOrderFactoryPartBService.applyFcPartCheck(baseRequestDIO.getOrderId());
			ApplyFactoryPartCheckDRO checkDRO = BeanMapper.map(checkDTO, ApplyFactoryPartCheckDRO.class);
			return ResponseDTO.success(checkDRO);
		} catch (OmsBaseException e) {
			return ResponseDTO.fail(e.getCode(), e.getMessage());
		}
	}

	/**
	 * 保留配件申请24小时
	 * @param retain24hourPartDIO
	 * @return
	 */
	@Override
	public ResponseDTO<Boolean> retain24hoursParts(Retain24hourPartDIO retain24hourPartDIO) {
		log.info("masterPartRemoteService#retain24hoursParts保留配件申请24小时=>入参:{}", JSON.toJSONString(retain24hourPartDIO));
		if (Objects.equals(retain24hourPartDIO.getRetainPart(), GlobalConsts.YES)) {
			OrderWork orderWork = orderWorkService.findOrderWorkByKey(retain24hourPartDIO.getOrderId(), retain24hourPartDIO.getWorkId());
			if (Objects.isNull(orderWork)) {
				return ResponseDTO.fail("订单不存在");
			}
			if (orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_CHECKOUT) {
				return ResponseDTO.fail("已收单不能操作保留配件");
			}
			// 已完成后操作保留配件--新增提醒任务
			if (Objects.equals(orderWork.getPartRetain(),GlobalConsts.NO)
					&& Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_COMPLETE)) {
				try {
					zsMasterWorkBService.addRetainPartJob(orderWork, DateUtil.getNow());
				} catch (Exception e) {
					log.error(e.getMessage(),e);
				}
			}
		}

		MasterPartRetainDTO masterPartRetainDTO = BeanMapper.map(retain24hourPartDIO, MasterPartRetainDTO.class);
		super.setLogParam(retain24hourPartDIO, masterPartRetainDTO);
		masterWorkBService.updatePartRetain(masterPartRetainDTO);
		return ResponseDTO.success(true);
	}
}
